/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.biz.service.impl;

import me.zhengjie.modules.biz.domain.ErrorLog;
import me.zhengjie.modules.biz.domain.Lab;
import me.zhengjie.modules.biz.domain.StorehouseOrder;
import me.zhengjie.modules.biz.repository.LabRepository;
import me.zhengjie.modules.biz.service.dto.StorehouseOrderDto;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.biz.repository.ErrorLogRepository;
import me.zhengjie.modules.biz.service.ErrorLogService;
import me.zhengjie.modules.biz.service.dto.ErrorLogDto;
import me.zhengjie.modules.biz.service.dto.ErrorLogQueryCriteria;
import me.zhengjie.modules.biz.service.mapstruct.ErrorLogMapper;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import me.zhengjie.utils.DateUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author Admin
* @date 2023-03-16
**/
@Service
@RequiredArgsConstructor
public class ErrorLogServiceImpl implements ErrorLogService {

    private final ErrorLogRepository errorLogRepository;
    private final ErrorLogMapper errorLogMapper;

    private final LabRepository labRepository;

    @Override
    public Map<String,Object> queryAll(ErrorLogQueryCriteria criteria, Pageable pageable){
        Page<ErrorLog> page = errorLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(errorLogMapper::toDto));
    }

    @Override
    public List<ErrorLogDto> queryAll(ErrorLogQueryCriteria criteria){
        return errorLogMapper.toDto(errorLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public ErrorLogDto findById(Integer id) {
        ErrorLog errorLog = errorLogRepository.findById(id).orElseGet(ErrorLog::new);
        ValidationUtil.isNull(errorLog.getId(),"ErrorLog","id",id);
        return errorLogMapper.toDto(errorLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ErrorLogDto create(ErrorLog resources) {
        return errorLogMapper.toDto(errorLogRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ErrorLog resources) {
        ErrorLog errorLog = errorLogRepository.findById(resources.getId()).orElseGet(ErrorLog::new);
        ValidationUtil.isNull( errorLog.getId(),"ErrorLog","id",resources.getId());
        errorLog.copy(resources);
        errorLogRepository.save(errorLog);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            errorLogRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<ErrorLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (ErrorLogDto errorLog : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(" name",  errorLog.getName());
            map.put("楼层", errorLog.getFloor());
            map.put("类型", errorLog.getType());
            map.put("报警位点id", errorLog.getPositionId());
            map.put("报警位点", errorLog.getPosition());
            map.put("报警值", errorLog.getValue());
            map.put("报警描述", errorLog.getDec());
            map.put("报警码", errorLog.getErrorCode());
            map.put("状态值", errorLog.getStatus());
            map.put(" createdAt",  errorLog.getCreatedAt());
            map.put(" updatedAt",  errorLog.getUpdatedAt());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Map<String, Object> currentList(ErrorLogQueryCriteria criteria, Pageable pageable) {
        Specification<ErrorLog> specification = (Specification<ErrorLog>) (root, query, criteriaBuilder) -> {
            Predicate p1 = criteriaBuilder.equal(root.get("status").as(Integer.class), 0);
            return criteriaBuilder.and(p1);
        };
        Page<ErrorLog> page = errorLogRepository.findAll(specification,pageable);
        Page<ErrorLogDto> dto = page.map(errorLogMapper::toDto);
        List<ErrorLogDto> resultDto = dto.getContent();
        for (ErrorLogDto errorLog: resultDto) {
            Lab lab = labRepository.findById(errorLog.getPositionId()).orElseGet(Lab::new);
            errorLog.setPosition(lab.getName());
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public Map<String, Object> historyList(ErrorLogQueryCriteria criteria, Pageable pageable) {
        Specification<ErrorLog> specification = (Specification<ErrorLog>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            if (criteria.getStartTime()!=null){
                predicates.add(criteriaBuilder.between(root.get("createdAt"),DateUtil.strToSqlDate(criteria.getStartTime()),DateUtil.strToSqlDate(criteria.getEndTime())));
            }
            predicates.add(criteriaBuilder.equal(root.get("status"), 1));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<ErrorLog> page = errorLogRepository.findAll(specification,pageable);
        Page<ErrorLogDto> dto = page.map(errorLogMapper::toDto);
        List<ErrorLogDto> resultDto = dto.getContent();
        for (ErrorLogDto errorLog: resultDto) {
            Lab lab = labRepository.findById(errorLog.getPositionId()).orElseGet(Lab::new);
            errorLog.setPosition(lab.getName());
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public Map<String, Object> floorList(ErrorLogQueryCriteria criteria, Pageable pageable) {
        Page<ErrorLog> page = errorLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(errorLogMapper::toDto));
    }

    @Scheduled(cron = "0 0 0 * * ?")
    public void judgmentTime() {
        try {
            Date date_early = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(DateFormatUtils.format(new Date(), "yyyy-MM-dd 00:00:00"));
            Date date_night = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(DateFormatUtils.format(new Date(), "yyyy-MM-dd 23:59:59"));
            Calendar cal = Calendar.getInstance();
            cal.setTime(date_early);
            long timestamp_early = cal.getTimeInMillis();
            cal.setTime(date_night);
            long timestamp_night = cal.getTimeInMillis();
            Specification<ErrorLog> specification = (Specification<ErrorLog>) (root, query, criteriaBuilder) -> {
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(criteriaBuilder.equal(root.get("status"), 0));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            };
            List<ErrorLog> errorLogList = errorLogRepository.findAll(specification);
            for (ErrorLog errorLog:errorLogList) {
                java.sql.Date dateTime = new java.sql.Date(errorLog.getCreatedAt().getTime());
                cal = Calendar.getInstance();
                cal.setTime(dateTime);
                long current_time = cal.getTimeInMillis();
                if (current_time<timestamp_early){
                    errorLog.setStatus(1);
                    errorLogRepository.save(errorLog);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
